package org.SimpleSpringBoot.container;


import org.SimpleSpringBoot.annotation.Autowired;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
Bean工厂，负责Bean的创建、管理和依赖注入
 */
public class BeanFactory {

    //初始化bean
    private final Map<String,BeanDefinition> beanDefinitions =new ConcurrentHashMap<>();

    //实例化Bean
    private final Map<String,Object> singletonBeans =new ConcurrentHashMap<>();


    /**
     * 注册Bean定义
     * @param beanName
     * @return
     */
    public void registerBeanDefinnition(String beanName,BeanDefinition beanDefinition){
        beanDefinitions.put(beanName,beanDefinition);
        System.out.println("注册Bean定义"+beanName+"-->"+beanDefinition.getBeanClass().getSimpleName());

    }

    //获取Bean实例
    public Object getBean(String beanName){
        Object bean = singletonBeans.get(beanName);
        if (bean!=null){
            return bean;
        }

        //获取Bean的定义
        BeanDefinition beanDefinition = beanDefinitions.get(beanName);
        if (beanDefinition==null){
            throw new RuntimeException("找不到Bean定义"+beanName);
        }

        //创建Bean实例
        bean = createBean(beanDefinition);
        if (beanDefinition.isSingleton()){
            singletonBeans.put(beanName,bean);
        }
        return bean;
    }
    /*
    根据类型获取Bean
     */
    public <T> T getBean(Class<T> requiredType){
        for (Map.Entry<String,BeanDefinition> entry:beanDefinitions.entrySet()){
            if (requiredType.isAssignableFrom(entry.getValue().getBeanClass())){
                return (T) getBean(entry.getKey());
            }
        }
         throw new RuntimeException("找不到类型为"+requiredType.getName()+"的Bean");
    }

    /*
    创建Bean实例
     */
    /**
     * 创建Bean实例
     */
    private Object createBean(BeanDefinition beanDefinition) {
        try {
            System.out.println("创建Bean实例: " + beanDefinition.getBeanClass().getSimpleName());

            // 检查是否已经有现成的实例（用于自动配置的Bean）
            if (beanDefinition.getInstance() != null) {
                Object instance = beanDefinition.getInstance();
                // 处理依赖注入
                injectDependencies(instance);
                return instance;
            }

            // 实例化Bean
            Object instance = beanDefinition.getBeanClass().getDeclaredConstructor().newInstance();

            // 处理依赖注入
            injectDependencies(instance);

            return instance;
        } catch (Exception e) {
            throw new RuntimeException("创建Bean失败: " + beanDefinition.getBeanClass().getName(), e);
        }
    }

    /*
    处理依赖注入
     */
    private void injectDependencies(Object instance) {

        Class<?> clazz = instance.getClass();

        //处理字段注入
        for (Field field: clazz.getDeclaredFields()){

            if(field.isAnnotationPresent(Autowired.class)){
                try {
                    field.setAccessible(true);
                    Object dependency =getBean(field.getName());
                    field.set(instance,dependency);
                    System.out.println("注入依赖："+field.getName()+"-->"+dependency.getClass().getSimpleName());
                }catch (Exception e){
                    throw new RuntimeException("依赖注入失败"+field.getName(),e);
                }
            }
        }
    }
    /*
    检查是否包含指定名称的Bean
     */
    public boolean containsBean(String beanName){
        return beanDefinitions.containsKey(beanName);
    }
    /*
    获取所有Bean定义
     */
    public Map<String,BeanDefinition> getAllBeanDefinitions(){
        return beanDefinitions;
    }







}
